package com.shiyu.common.security.service;

import com.shiyu.common.core.constants.CacheConstants;
import com.shiyu.common.core.constants.JwtConstants;
import com.shiyu.common.redis.service.RedisService;
import com.shiyu.common.core.Utils.JwtUtils;

import java.util.HashMap;
import java.util.Map;
import cn.hutool.core.lang.UUID;
import com.shiyu.common.core.domain.LoginUser;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

//操作用户登录token的方法
@Service
@Slf4j
public class TokenService {
    @Autowired
    private RedisService redisService;


    public String createToken(Long userId,String secret,Integer identity){
        Map<String ,Object> claims=new HashMap<>();
        String userKey= UUID.fastUUID().toString();
        claims.put(JwtConstants.LOGIN_USER_ID,userId);
        claims.put(JwtConstants.LOGIN_USER_KEY,userKey);
        String token= JwtUtils.createToken(claims,secret);
//            第三方机制存储敏感信息使用redis
//            身份认证具体还要存储哪一些信息,使用什么样的数据结构 过期时间应该多长
//            表明用户身份的字段 Integer identity string list hash set zset
//            key必须保证唯一便于维护 统一的前缀 logintoken:使用userId 雪花算法生成的唯一主键
//            Integer identity=
//                    1表示普通用户,2表示管理员 720分钟
        String tokenkey=getTokenKey(userKey);
        LoginUser loginUser=new LoginUser();
        loginUser.setIdentity(identity);
//            720redis数据的过期时间
        redisService.setCacheObject(tokenkey,loginUser,CacheConstants.EXP, TimeUnit.MINUTES);
        return token;
    }
//    延长token的有效时间
    public void extendToken(String token,String secret){
//        redis中的敏感信息,实际上延长token的有效时间,就是延长redis中的敏感信息的有效时间,操作redis 通过token拿到唯一标识
        Claims claims;
        try {
            claims = JwtUtils.paresToken(token, secret); //获取令牌中信息  解析payload中信息  存储着用户唯一标识信息
            if (claims == null) {
                //springcloud gateway 基于webflux
//                return unauthorizedResponse(exchange, "令牌已过期或验证不正确！");
//                todo
                log.error("解析token出现异常");
                return;
            }
        } catch (Exception e) {
//            return unauthorizedResponse(exchange, "令牌已过期或验证不正确！");
//            todo
            log.error("解析token出现异常");
            return;
        }
//        获取jwt中的key
         String userkey=JwtUtils.getUserKey(claims);
         String tokenkey= getTokenKey(userkey);
//         720min 12个小时
//        判断一个临界值  剩余180分钟的时候,进行延长,拿到原先的有效时间
        Long expire=redisService.getExpire(tokenkey,TimeUnit.MINUTES);
//     对这个值进行判断
        if(expire!=null&&expire<CacheConstants.REFRESH_TIME){
//            进行延长
//            重新设计时间
            redisService.expire(token,CacheConstants.EXP,TimeUnit.MINUTES);
        }
    }
    private  String getTokenKey(String userKey){
        return CacheConstants.LOGIN_TOKEN_KEY +userKey;
    }
}
